package com.zh.media.service.impl;

import cn.hutool.core.bean.BeanUtil;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.zh.common.exception.BusinessException;
import com.zh.common.properties.JwtProperties;
import com.zh.media.Thread.FixedThreadPool;
import com.zh.media.domain.dto.AddReplyDto;
import com.zh.media.domain.dto.PageReplyDto;
import com.zh.media.domain.vo.ReplyVo;
import com.zh.media.mapper.ReplyInfoMapper;
import com.zh.media.mapper.ReplyMapper;
import com.zh.media.service.ReplyService;
import com.zh.web.base.PageApiResult;
import com.zh.web.domain.auth.dto.UserDto;
import com.zh.web.domain.auth.vo.UserVo;
import com.zh.web.domain.media.entity.Reply;
import com.zh.web.openApi.AuthClient;
import com.zh.web.openApi.UserClient;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;

import javax.servlet.http.HttpServletRequest;
import java.util.List;
import java.util.Map;
import java.util.Optional;
import java.util.Set;
import java.util.concurrent.CompletableFuture;
import java.util.stream.Collectors;

/**
 * <p>
 * 服务实现类
 * </p>
 *
 * @author zh
 * @since 2024-10-02
 */
@Service
@Slf4j
@RequiredArgsConstructor
public class ReplyServiceImpl extends ServiceImpl<ReplyMapper, Reply> implements ReplyService {


    private final ReplyMapper replyMapper;
    private final ReplyInfoMapper replyInfoMapper;
    private final UserClient userClient;
    private final AuthClient authClient;
    private final JwtProperties jwtProperties;

    @Override
    public ReplyVo getReplyVo(Long id) {
        Reply reply = replyMapper.selectById(id);
        ReplyVo replyVo = BeanUtil.copyProperties(reply, ReplyVo.class);
        UserDto userDto = new UserDto();
        userDto.setId(reply.getUserId());
        UserVo user = userClient.getUserInfo(userDto).getData();
        replyVo.setAvatar(user.getAvatar());
        replyVo.setNickName(user.getNickname());
        return replyVo;
    }

    @Override
    public PageApiResult<ReplyVo> pageReply(PageReplyDto pageReplyDto, HttpServletRequest request) {
        Long userId;
        Map<String, Object> sessionMap = authClient.getSessionByToken(request.getHeader(jwtProperties.getTokenName())).getData();
        if (sessionMap != null) {
            userId = Long.parseLong(sessionMap.get("id").toString());
        } else {
            userId = null;
        }
        pageReplyDto.setPageNum(pageReplyDto.getPageNum() < 1L ? 1L : pageReplyDto.getPageNum());
        pageReplyDto.setPageSize(pageReplyDto.getPageSize() < 1L ? 10L : pageReplyDto.getPageSize());
        IPage<ReplyVo> page = new Page<>(pageReplyDto.getPageNum(), pageReplyDto.getPageSize());
        List<ReplyVo> replyVoList = replyMapper.page(page, pageReplyDto);
        //1.查用户信息
        CompletableFuture<Void> userTask = CompletableFuture.runAsync(() -> {
            Set<Long> userIdSet = replyVoList.stream().map(ReplyVo::getUserId).collect(Collectors.toSet());
            List<UserVo> userVoList = userClient.listUser(userIdSet).getData();
            Map<Long, UserVo> userMap = userVoList.stream()
                    .collect(Collectors.toMap(UserVo::getId, userVo -> userVo));
            replyVoList.forEach(replyVo -> {
                UserVo userVo = userMap.get(replyVo.getUserId());
                replyVo.setNickName(userVo.getNickname());
                replyVo.setAvatar(userVo.getAvatar());
            });
            //2.标记我的回复
            replyVoList.forEach(replyVo -> {
                if (replyVo.getUserId().equals(userId)) {
                    replyVo.setByMe(true);
                }
            });
        }, FixedThreadPool.fixedThreadPool);
        CompletableFuture.allOf(userTask).join();
        page.setRecords(replyVoList);
        return PageApiResult.<ReplyVo>builder()
                .pageNum(page.getCurrent())
                .total(page.getTotal())
                .list(page.getRecords())
                .pageSize(page.getSize())
                .build();
    }

    @Override
    public String save(AddReplyDto addReplyDto) {
        Optional.ofNullable(addReplyDto.getWorksId())
                .orElseThrow(() -> new RuntimeException("作品Id不能为空"));
        Optional.ofNullable(addReplyDto.getUserId())
                .orElseThrow(() -> new RuntimeException("用户Id不能为空"));
        Optional.ofNullable(addReplyDto.getContent())
                .orElseThrow(() -> new RuntimeException("评论内容不能为空"));
        Reply reply = BeanUtil.copyProperties(addReplyDto, Reply.class);
        boolean success = replyMapper.insert(reply) > 0;
        if (success) {
            return "评论成功";
        } else {
            throw new BusinessException("评论成功");
        }
    }

    @Override
    public String delete(Long id) {
        boolean success = replyMapper.deleteById(id) > 0;
        if (success) {
            return "删除成功";
        } else {
            throw new BusinessException("删除失败");
        }
    }
}
